import select, time


from libs.dae.ip import IP

import config

from protocols.bncc import BNCCSocket
from protocols.bncs import BNCSSocket
from protocols.bnftpc import BNFTPCSocket
from protocols.bnftps import BNFTPSSocket
from protocols.client import ClientSocket
from protocols.server import ServerSocket
from protocols.d2rc import D2RCSocket
from protocols.d2rs import D2RSSocket
from protocols.d2gc import D2GCSocket
from protocols.d2gs import D2GSSocket
from protocols.bnp import BNPSocket

# Diablo II Game Server/Client Protocol
D2GS_PROTOCOL = 5
D2GC_PROTOCOL = 5

# Battle.net FTP Server/Client Protocol
BNFTPS_PROTOCOL = 2
BNFTPC_PROTOCOL = 2

# Battle.net Chat Server/Client Protocol
BNCS_PROTOCOL = 1
BNCC_PROTOCOL = 1

# Diablo II Realm Server/Client Protocol
D2RS_PROTOCOL = 4
D2RC_PROTOCOL = 4

def cleanSockets():
	for sock in config.read:
		try:
			r, w, e = select.select([sock], [], [], 0)
		except:
			sock.close()
			config.read.remove(sock)
			config.write.remove(sock)

	for sock in config.write:
		try:
			r, w, e = select.select([], [sock], [], 0)
		except:
			sock.close()
			config.read.remove(sock)
			config.write.remove(sock)

class Server:
	def initialize(self, greenvex):
		greenvex.Invalidate += self.main
	
	def main(self):
		jobsLastChecked = 0
		
		while True:
				cleanSockets()
				
				r, w, e = select.select(config.read, config.write, config.error, 0)
				
				for sock in r:
						if sock.__class__.__name__ == "BNPSocket":
								client, (host, port) = sock.accept()
								client.setblocking(1)
								protocol = ord(client.recv(1, 2))
								
								if protocol is BNCC_PROTOCOL:
										client = BNCCSocket(client._sock)
										server = BNCSSocket()
								elif protocol is BNFTPC_PROTOCOL:
										client = BNFTPCSocket(client._sock)
										server = BNFTPSSocket()
								else:
										client = ClientSocket(client._sock)
										server = ServerSocket()
								
								client.listeners.append(server)
								server.listeners.append(client)
								
								client.source = sock.source
								server.source = IP(sock.source.host, random.randint(10000, 50000))
								
								client.destination = IP(host, port)
								server.destination = sock.destination
								
								server.bind()
								server.connect()
								
								config.read.append(client)
								config.write.append(client)
								
								for listener in client.listeners:
										config.read.append(listener)
										config.write.append(listener)
						
						elif sock.__class__.__name__ == "D2RPSocket":
								client, (host, port) = sock.accept()
								
								client = D2RCSocket(client)
								server = D2RSSocket()
								
								client.listeners.append(server)
								server.listeners.append(client)
								
								client.source = sock.source
								server.source = IP(sock.source.host, random.randint(10000, 50000))
								
								client.destination = IP(host, port)
								server.destination = sock.destination
								
								server.bind()
								server.connect()
								
								config.read.append(client)
								config.write.append(client)
								
								for listener in client.listeners:
										config.read.append(listener)
										config.write.append(listener)
						
						elif sock.__class__.__name__ == "D2GPSocket":
								client, (host, port) = sock.accept()
								
								client = D2GCSocket(client)
								server = D2GSSocket()
								
								client.listeners.append(server)
								server.listeners.append(client)
								
								client.source = sock.source
								server.source = IP(sock.source.host, random.randint(10000, 50000))
								
								client.destination = IP(host, port)
								server.destination = sock.destination
								
								server.bind()
								server.connect()
								
								config.read.append(client)
								config.write.append(client)
								
								for listener in client.listeners:
										config.read.append(listener)
										config.write.append(listener)
						
						else:
								sock.data = sock.read()
								
								if sock.data:
										sock.unpackPackets()
										
										while len(sock.packets) > 0:
												message = sock.packets.pop().pack()
												
												for listener in sock.listeners:
														listener.write(message)
				
				time.sleep(0.1)

def main():
    return Server()